package cn.tedu.autoshow.website.service.impl;

import cn.tedu.autoshow.commons.ex.ServiceException;
import cn.tedu.autoshow.commons.pojo.vo.PageData;
import cn.tedu.autoshow.commons.util.PageInfoToPageDataConverter;
import cn.tedu.autoshow.commons.web.ServiceCode;
import cn.tedu.autoshow.website.mapper.TicketListMapper;
import cn.tedu.autoshow.website.pojo.entity.TicketList;
import cn.tedu.autoshow.website.pojo.param.TicketListAddNewParam;
import cn.tedu.autoshow.website.pojo.param.TicketListUpdaeInfoParam;
import cn.tedu.autoshow.website.pojo.vo.TicketListListItemVO;
import cn.tedu.autoshow.website.pojo.vo.TicketListStandardVO;
import cn.tedu.autoshow.website.service.ITicketListService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static cn.tedu.autoshow.commons.constants.StatusConstants.*;

@Service
@Slf4j
public class TicketListServiceImpl implements ITicketListService {

    @Autowired
    TicketListMapper mapper;

    @Override
    public void addNew(TicketListAddNewParam cvsTicketListAddNewParam ) {
        log.info("【开始】:【新增—票单列表】");
        log.debug("传入参数, cvsTicketOrderAddNewParam={}", cvsTicketListAddNewParam);
        TicketList cvsTicketList =new TicketList();
        BeanUtils.copyProperties(cvsTicketListAddNewParam, cvsTicketList);
        cvsTicketList.setGmtCreate(LocalDateTime.now());
        cvsTicketList.setGmtModified(LocalDateTime.now());


        log.debug("整合实体, banner={}", cvsTicketList);
        int insert = mapper.insert(cvsTicketList);
        log.info("【结果1】:插入数据结果, insert = {}", insert);
    }

    @Override
    public void deleteById(Long id) {
        log.info("【开始】:【根据ID删除—票单列表】");
        log.debug("传入参数, id={}", id);
        //检查票单列表ID检查票单列表是否存在数据，如果不存在，则抛出异常
        QueryWrapper<TicketList> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("id", id);
        int countById = mapper.selectCount(queryWrapper2);
        log.info("规则：根据票单列表id检索数据库结果,countById={}", countById);
        if(countById == 0){
            log.info("结果2:根据票单列表id检索数据量为0，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "删除票单列表失败，票单列表数据不存在！");
        }


        int delete = mapper.deleteById(id);
        log.info("【结果1】:删除数据结果, delete = {}", delete);
    }

    @Override
    public void updateInfoById(Long id, TicketListUpdaeInfoParam cvsTicketListUpdaeInfoParam) {
        log.info("【开始】:【根据ID更新—票单列表】");
        log.debug("传入参数, id={}, bannerAddNewParam={}", id, cvsTicketListUpdaeInfoParam);

        //检查票单列表ID检查票单列表是否存在数据，如果不存在，则抛出异常
        QueryWrapper<TicketList> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("id", id);
        int countById = mapper.selectCount(queryWrapper2);
        log.info("规则：根据票单列表id检索数据库结果,countById={}", countById);
        if(countById == 0){
            log.info("结果2:根据票单列表id检索数据量为0，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "编辑票单列表失败，票单列表数据不存在！");
        }

        TicketList cvsTicketList =new TicketList();
        BeanUtils.copyProperties(cvsTicketListUpdaeInfoParam, cvsTicketList);
        cvsTicketList.setId(id);
        log.debug("整合实体, banner={}", cvsTicketList);
        int update = mapper.updateById(cvsTicketList);
        log.info("【结果1】:更新数据结果, update = {}", update);
    }

    @Override
    public void setPayRefundById(Long id) {
        List<Integer> preStatus = new ArrayList<>();
        preStatus.add(PAY_PAID);
        preStatus.add(PAY_REFUND_FAIL);
        updatePayStatusById(id, PAY_REFUND, preStatus);
    }

    @Override
    public void setPayRefundedById(Long id) {
        List<Integer> preStatus = new ArrayList<>();
        preStatus.add(PAY_REFUND);
        updatePayStatusById(id, PAY_REFUNDED, preStatus);
    }

    @Override
    public void setPayRefundFailById(Long id) {
        List<Integer> preStatus = new ArrayList<>();
        preStatus.add(PAY_REFUND);
        updatePayStatusById(id, PAY_REFUND_FAIL, preStatus);
    }

    private void updatePayStatusById(Long id, Integer payStatus, List<Integer> preStatus){
        String text = PAY_STATUS_TEXT[payStatus];
        log.info("开始:审核购票【" + text + "】");
        log.debug("传入参数,id={}, payStatus={} ", id, payStatus);

        //检查数据是否存在，如果不存在，则抛出异常
        TicketListStandardVO standardById = mapper.getStandardById(id);
        log.info("规则：根据购票列表id检索数据库结果,standardById={}", standardById);
        if(standardById == null){
            log.info("结果2:根据购票列表id检索数据量为0，抛出异常...");
            String message = "审核购票" + text + "失败，管理员数据不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        if(standardById.getPayStatus() == payStatus){
            String message = "审核购票" + text + "失败，此票单已经处于" + text + "状态！";
            log.info("结果3:根据购票当前状态与要修改状态一致，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //状态流转有前置状态要求
        if(!preStatus.contains(standardById.getPayStatus())){
            String message = "审核购票" + text + "失败，此票单流转异常，未处于前置状态！";
            log.info("结果4:根据购票当前状态不为修改状态的前置状态，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        TicketList ticketList = new TicketList();
        ticketList.setId(id).setPayStatus(payStatus);
        int rows = mapper.updateById(ticketList);
        if(rows != 1){
            String message = "审核购票" + text+"失败，服务器忙，请稍后再试！";
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", 1, rows);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
        log.info("结果1:根据id更新购票结果,rows={}", rows);
    }

    @Override
    public TicketListStandardVO getStandardById(Long id) {
        log.info("开始:【根据ID查询-票单列表】");
        log.debug("传入参数,id={}", id);
        TicketListStandardVO standardById=mapper.getStandardById(id);

        //根据票单列表ID检查票单列表是否存在数据，如果不存在，则抛出异常
        if(standardById==null){
            log.info("结果2:根据票单列表id查询详情，结果为null，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "查询票单列表详情失败，票单列表数据不存在");
        }

        log.info("结果1:查询出数据,standardById");
        return standardById;
    }

    @Override
    public List<TicketListListItemVO> listByOrderId(Long orderId){
        log.info("开始:【查询-票单列表】");
        log.debug("传入参数, orderId={}", orderId);
        List<TicketListListItemVO> list = mapper.listByOrderId(orderId);
        log.debug("结果1: 查询结果：list={}", list);
        return list;
    }

    @Override
    public PageData<TicketListListItemVO> list(Integer pageNum) {
        Integer pageSize = 5;
        return list(pageNum, pageSize);
    }

    @Override
    public PageData<TicketListListItemVO> list(Integer pageNum, Integer pageSize) {
        log.info("开始:【查询-票单列表-分页】");
        log.debug("传入参数, pageNum={}, pageSize={}", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<TicketListListItemVO> list = mapper.list();
        PageInfo<TicketListListItemVO> pageInfo = new PageInfo<>(list);
        PageData<TicketListListItemVO> pageData = PageInfoToPageDataConverter.converter(pageInfo);
        log.debug("结果1: 查询结果：pageData={}", pageData);
        return pageData;
    }

    @Override
    public PageData<TicketListListItemVO> listByPatStatus(Integer payStatus, Integer pageNum){
        Integer pageSize = 5;
        return listByPatStatus(payStatus, pageNum, pageSize);
    }

    @Override
    public PageData<TicketListListItemVO> listByPatStatus(Integer payStatus, Integer pageNum, Integer pageSize){
        log.info("开始:【查询-票单列表-分页】");
        log.debug("传入参数, pageNum={}, pageSize={}", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<TicketListListItemVO> list = mapper.listByPatStatus(payStatus);
        PageInfo<TicketListListItemVO> pageInfo = new PageInfo<>(list);
        PageData<TicketListListItemVO> pageData = PageInfoToPageDataConverter.converter(pageInfo);
        log.debug("结果1: 查询结果：pageData={}", pageData);
        return pageData;
    }
}
